package com.myk.game.gobangchess.rooms.oldrooms;

import com.myk.game.gobangchess.constants.BoardStyleData;
import com.myk.game.gobangchess.constants.WinMode;
import com.myk.game.gobangchess.rooms.absrooms.AbsOneTwoTwoTwoStepRoom;
import com.myk.game.gobangchess.signs.TextSign;

/**
 * 六子棋房间
 */
public class Connect6PlusRoom extends AbsOneTwoTwoTwoStepRoom {
    final static int size=19;
    public Connect6PlusRoom(String roomName) {
        super(roomName, "\t\t加强版六子棋，增加了禁着点，避免和棋的同时增加了可玩性。", "六子棋Plus",BoardStyleData.getGoBangStyle(size,size),true,true);
    }

    @Override
    public String getRuleText() {
        return "黑棋先落一枚棋子，\n" +
                "随后白黑双方轮流落下两枚棋子，\n" +
                "禁止在不可能参与六连的位置落子。\n" +
                "获胜条件：形成六子一线或对方无子可走";
    }
    byte[][][]state=new byte[size][size][2];
    int[]mobeableCount={size*size,size*size};
    @Override
    public void resetGrids() {
        super.resetGrids();
        for(int i=0;i<size;i++){
            for(int j=0;j<size;j++){
                if(i+j<6||size-i+size-j<6){
                    state[i][j][0]=2;
                    state[i][j][1]=2;
                }else if(size-i+j<6||size-j+i<6){
                    state[i][j][0]=8;
                    state[i][j][1]=8;
                }else{
                    state[i][j][0]=0;
                    state[i][j][1]=0;
                }
            }
        }
        mobeableCount[0]=size*size;
        mobeableCount[1]=size*size;
    }
    boolean checkLine(int row,int col,int offx,int offy,int value){
        int cnt=1;
        int i=row+offx,j=col+offy;
        while(i<size&&i>=0&&j<size&&j>=0&&curGrids[i][j]!=value){
            i+=offx;
            j+=offy;
            cnt++;
        }
        i=row-offx;j=col-offy;
        while(i<size&&i>=0&&j<size&&j>=0&&curGrids[i][j]!=value){
            i-=offx;
            j-=offy;
            cnt++;
        }
        return cnt>=6;
    }
    final static int[][] dxdy = {
        {1, 0}, {-1, 1}, {0, 1}, {1, 1}
    };
    @Override
    public void doRule(int row, int col, int value) {
        if((state[row][col][value-1]!=0x0f)&&curGrids[row][col] == 0){
            int other=3-value;
            for(int d=0;d<4;d++){
                for(int s=-1;s<=1;s+=2){
                    int i=1;
                    boolean flag=false;
                    for(;i<7&&!flag;i++){
                        final int x=row+dxdy[d][0]*i*s,y=col+dxdy[d][1]*i*s;
                        if(x<0||y<0||x>=size||y>=size){
                            flag=true;
                        }
                        if(flag||curGrids[x][y] == value){
                            for(int j=1;j<i;j++){
                                final int x1=row+dxdy[d][0]*j*s,y1=col+dxdy[d][1]*j*s;
                                if(curGrids[x1][y1] ==0&&(state[x1][y1][other-1]&(1<<d))==0){
                                    state[x1][y1][other-1]|=1<<d;
                                    if(state[x1][y1][other-1]==0xf){
                                        mobeableCount[other-1]--;
                                    }
                                }
                            }
                        }
                    }
                }
            }
            if(state[row][col][other-1]!=0xf){
                mobeableCount[other-1]--;
            }
            mobeableCount[value-1]--;
            state[row][col][0]=0;
            state[row][col][1]=0;
            super.doRule(row, col, value);
        }
    }

    @Override
    public String getGameInfo() {
        signList.clear();
        signList.addAll(tempPointSigns);
        for(int i=0;i<size;i++){
            for(int j=0;j<size;j++){
                if(curGrids[i][j]==0){
                    if(state[i][j][0]==0x0f){
                        if(state[i][j][1]==0x0f){
                            signList.add(new TextSign(getIndex(i, j) ,"X", "#FFFF0000"));
                        }else{
                            signList.add(new TextSign(getIndex(i, j) ,"X", "#FF000000"));
                        }
                    }else if(state[i][j][1]==0x0f){
                        signList.add(new TextSign(getIndex(i, j) ,"X", "#FFFFFFFF"));
                    }
                }
            }
        }
        return super.getGameInfo();
    }


    @Override
    protected WinState checkWin(int row, int col) {
        int winValue = 0;
        for (int i = 0; i < dxdy.length; i++) {
            int dx = dxdy[i][0], dy = dxdy[i][1];
            int length = getJudgeLength(row, col, dx, dy) + getJudgeLength(row, col, -dx, -dy) - 1;
            if (length >= 6) {
                winValue = (curGrids[row][col] + 1) % 2 + 1;
            }
        }
        if (winValue == 1) {
            return new WinState(WinMode.BLACK_WIN,player_black.getNickNameOrTemp() + "执黑棋战胜" + player_white.getNickNameOrTemp());
        }
        else if (winValue == 2) {
            return new WinState(WinMode.WHITE_WIN,player_white.getNickNameOrTemp() + "执白棋战胜" + player_black.getNickNameOrTemp());
        }
        else if((step&2)==0){
            if(mobeableCount[1]==0){
                return new WinState(WinMode.BLACK_WIN,player_black.getNickNameOrTemp() + "执黑棋战胜" + player_white.getNickNameOrTemp());
            }
        }
        else {
            if(mobeableCount[0]==0){
                return new WinState(WinMode.WHITE_WIN,player_white.getNickNameOrTemp() + "执白棋战胜" + player_black.getNickNameOrTemp());
            }
        }
        return null;
    }

}